package me.pearjelly.crawler;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.regex.Pattern;

import me.pearjelly.filters.VisitFilter;
import me.pearjelly.filters.commons.DepthFilter;
import me.pearjelly.filters.commons.DomainFilter;
import me.pearjelly.filters.commons.UrlFilter;
import me.pearjelly.model.Image;
import me.pearjelly.model.PageContext;
import me.pearjelly.util.ImageQueue;
import me.pearjelly.util.JpegMetadataUtil;
import me.pearjelly.util.PageContextUtil;

import com.drew.metadata.Metadata;

import edu.uci.ics.crawler4j.crawler.Page;
import edu.uci.ics.crawler4j.crawler.WebCrawler;
import edu.uci.ics.crawler4j.url.WebURL;

public class MoXiuCrawler extends WebCrawler {

	private static final String filters = ".*(\\.(css|js|mid|mp2|mp3|mp4|wav|avi|mov|mpeg|ram|m4v|pdf|rm|smil|wmv|swf|wma|zip|rar|gz|bmp|gif|png|tiff?))$";
	private static final Pattern endPagePatterns = Pattern
			.compile(".*(\\.html)$");
	private static final Pattern imgPatterns = Pattern
			.compile(".*(\\.(jpe?g))$");
	private static int minWidth = 300;
	private static int minHeight = 300;
	private static File storageFolder;
	private static VisitFilter visitFilter = null;
	static {
		visitFilter = new DepthFilter(3, visitFilter);
		visitFilter = new UrlFilter(filters, visitFilter);
	}

	public static void configure(String[] domains, String storageFolderName) {
		storageFolder = new File(storageFolderName);
		if (!storageFolder.exists()) {
			storageFolder.mkdirs();
		}
		visitFilter = new DomainFilter(domains, visitFilter);
	}

	@Override
	public boolean shouldVisit(WebURL webURL) {
		return visitFilter.filter(webURL);
	}

	@Override
	public void visit(Page page) {
		String url = page.getWebURL().getURL().toLowerCase();
		if (!page.isBinary() && endPagePatterns.matcher(url).matches()) {
			PageContextUtil.putInCache(page.getWebURL().getDocid(), new PageContext(page));
		} else if (page.isBinary() && imgPatterns.matcher(url).matches()) {
			ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
					page.getBinaryData());
			Metadata metadata = JpegMetadataUtil
					.readMetadata(byteArrayInputStream);
			int width = JpegMetadataUtil.getWith(metadata);
			int height = JpegMetadataUtil.getHeight(metadata);
			if (width > minWidth && height > minHeight) {
				ImageQueue.offer(new Image(new PageContext(page), metadata, null));
			}
		}
	}
}
